﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using FlanProjectData.Managers;
using FlanProjectData.GameObjects;
using FlanProjectData.Sprites;

namespace FlanProjectData.Skills
{
    public class MoveList
    {
        private Skill[] moves;

        public MoveList(IEnumerable<Skill> moves)
        {
            // Store the list of moves in order of decreasing sequence length.
            // This greatly simplifies the logic of the DetectMove method.
            this.moves = moves.OrderByDescending(m => m.Sequence.Length).ToArray();
        }

        // Find the longest Move which matches the given input, if any.
        public Skill DetectMove()
        {
            // Perform a linear search for a move which matches the input. This relies
            // on the moves array being in order of decreasing sequence length.
            foreach (var move in moves)
            {
                if (SequenceManager.Matches(move))
                {
                    return move;
                }
            }

            return null;
        }

        public int LongestMoveLength
        {
            get
            {
                // Since they are in decreasing order,
                // the first move is the longest.
                return moves[0].Sequence.Length;
            }
        }
    }

    public class Skill
    {
        public String Name { get; set; }
        public SkillStat Stats { get; set; }

        public enum Types { Weak, Medium, Strong, Spell }
        public Types Type { get; set; }

        // The animation of the skill used
        public Animation SkillAnimation { get; set; }

        [ContentSerializerIgnore]
        public AnimatingSprite CurrentAnimation { get; set; }

        // The sequence of button presses required to activate this move.
        public SequenceManager.Action[] Sequence;

        // Set this to true if the input used to activate this move may be reused as a component of longer moves
        public bool IsCancellable { get; set; }

        public Skill()
        {
            SkillAnimation = new Animation();
            CurrentAnimation = new AnimatingSprite();
        }

        public Skill(string name, params SequenceManager.Action[] sequence)
        {
            Name = name;
            Sequence = sequence;
            SkillAnimation = new Animation();
            CurrentAnimation = new AnimatingSprite();
        }

        public void LoadContent(ContentManager contentManager)
        {
            SkillAnimation.LoadContent(contentManager);
            CurrentAnimation.PlayAnimation(SkillAnimation);
        }

        public void Draw(SpriteBatch spriteBatch, SpriteEffects spriteEffect, Vector2 position, GameTime gameTime)
        {
            CurrentAnimation.Draw(spriteBatch, spriteEffect, position, gameTime);
        }
    }
}
